package it.koutifaris.travianmap.map.randommap;

import it.koutifaris.travianmap.model.Player;
import it.koutifaris.travianmap.model.Tribe;
import it.koutifaris.travianmap.model.Village;
import it.koutifaris.travianmap.tile.Tile;
import it.koutifaris.travianmap.tile.TileBounds;
import it.koutifaris.travianmap.tile.bounds.DefaultTileBounds;
import it.koutifaris.travianmap.ui.PointToSquareHelper;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class RandomTile implements Tile {

	private static final int TILE_SIZE = TileBounds.DEFAULT_TILE_SIZE;
	private static final int MAX_NUM_OF_VILLAGES = TILE_SIZE * TILE_SIZE / 4;
	private static final int MIN_NUM_OF_VILLAGES = 2;

	private static int villageId = 0;

	private List<Village> villages;
	private final DefaultTileBounds tileBoundsImpl;

	public RandomTile(int x, int y) {
		PointToSquareHelper helper = new PointToSquareHelper(TILE_SIZE);
		int cornerX = helper.getSquareCornerFromPoint(x);
		int cornerY = helper.getSquareCornerFromPoint(y);
		tileBoundsImpl = DefaultTileBounds.builder()
				.setOrigin(cornerX, cornerY)
				.withDefaultSize()
				.build();

		initVillages(cornerX, cornerY);
	}

	private void initVillages(int cornerX, int cornerY) {
		Random random = new Random();
		int numVillages = MIN_NUM_OF_VILLAGES + random.nextInt(MAX_NUM_OF_VILLAGES - MIN_NUM_OF_VILLAGES);

		Player[] players = initPlayers();
		villages = new ArrayList<Village>(numVillages);
		for (int i = 0; i < numVillages; i++) {
			int x = cornerX + random.nextInt(TILE_SIZE);
			int y = cornerY + random.nextInt(TILE_SIZE);
			Player player = players[random.nextInt(3)];
			Village village = new RandomVillage(nextVillageId(), player, x, y);
			villages.add(village);
			player.getVillages().add(village);
		}
	}

	private Player[] initPlayers() {
		Player[] players = new Player[3];

		players[0] = new RandomPlayer(Tribe.ROMAN);
		players[1] = new RandomPlayer(Tribe.GAUL);
		players[2] = new RandomPlayer(Tribe.TEUTON);

		return players;
	}

	@Override
	public Iterable<Village> getVillages() {
		return villages;
	}

	@Override
	public int getNumberOfVillages() {
		return villages.size();
	}

	@Override
	public TileBounds getBounds() {
		return tileBoundsImpl;
	}

	private int nextVillageId() {
		return villageId++;
	}

}
